﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using System.Reflection;
using SystemX;
namespace SystemX.Web
{
    public static partial class ObjectX
    {
        /// <summary>
        /// Load a control with specified constructor parameters
        /// </summary>
        /// <param name="page"></param>
        /// <param name="UserControlPath"></param>
        /// <param name="constructorParameters"></param>
        /// <returns></returns>
        public static UserControl LoadControl(this Page page, string UserControlPath, params object[] constructorParameters)
        {
            List<Type> constParamTypes = new List<Type>();
            foreach (object constParam in constructorParameters)
            {
                constParamTypes.Add(constParam.GetType());
            }

            UserControl ctl = page.LoadControl(UserControlPath) as UserControl;

            // Find the relevant constructor
            ConstructorInfo constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());

            //And then call the relevant constructor
            if (constructor == null)
            {
                throw new MemberAccessException(String.Format("The requested constructor was not found on : {0}", ctl.GetType().BaseType));
            }
            else
            {
                constructor.Invoke(ctl, constructorParameters);
            }

            // Finally return the fully initialized UC
            return ctl;
        }
        /// <summary>
        /// Convert the query value of a specified query key on the page to a Dictionary{string,object}.
        /// E.g,Use GetQData("d") to parse the query string d={x:1,y:'2'} to a dictionary. 
        /// </summary>
        /// <param name="page">System.Web.UI.Page instance</param>
        /// <param name="querykey">Query string key</param>
        /// <returns></returns>
        /// <remarks>
        /// This extension method is for the sake of ajax trick on asp.net's query string.
        /// <see cref="http://vivasky.com/dotnet"/>
        /// </remarks>
        public static Dictionary<string, object> GetQData(this Page page, string querykey)
        {
            Check.Require((!string.IsNullOrEmpty(querykey)), "Parameter must be specified!");
            //no such key
            if (!page.Request.QueryString.AllKeys.Contains(querykey))
            {
                return new Dictionary<string, object>();
            }
            //parse the value
            try
            {
                return page.Request.QueryString[querykey].DeserializeJSONStr<Dictionary<string, object>>();
            }
            catch (Exception ex)
            {
                return new Dictionary<string, object>();
            }
        }
        /// <summary>
        /// render a partial view
        /// </summary>
        /// <param name="viewVPath">virtual path of the view,such as '~/view/view1.ascx'</param>
        /// <returns></returns>
        public static string RenderV<T>(this IHtmlWriterControl ctr, string viewVPath,bool dependingPage, bool verifyRenderingInForm, Action<T> action) where T : Control
        {

            var vm = new ViewManager<T>(viewVPath, dependingPage?ctr.CurPage:null, verifyRenderingInForm);
            if (null != action)
            {
                action(vm.Control);
            }
            var retVal = vm.Render();
            return retVal;
        }
        /// <summary>
        /// render a partial view
        /// </summary>
        /// <param name="viewVPath">virtual path of the view,such as '~/view/view1.ascx'</param>
        /// <returns></returns>
        public static void RenderV<T>(this IHtmlWriterControl ctr, bool dependingPage, bool verifyRenderingInForm, string viewVPath, Action<T> action) where T : Control
        {
            var vm = new ViewManager<T>(viewVPath, dependingPage ? ctr.CurPage : null, verifyRenderingInForm);
            if (null != action)
            {
                action(vm.Control);
            }
            vm.Render(ctr);
        }
    }
}
